
from rest_framework.authentication import BaseAuthentication
from api import models
from rest_framework import exceptions

#修改里面的参数使得request.user/request.autn默认值为None
from rest_framework.request import Request

class GeneralAuthentication(BaseAuthentication):
    """
    通用认证，如果认证成功则返回数据，认证失败自己不处理，交给下一个认证组件处理
    """
    def authenticate(self, request):
        token = request.META.get('HTTP_AUTHORIZATION',None)
        #1.如果用户没有提供token，返回None(我不处理，交给下一个认证类处理，则默认是None)
        if not token:
            return None
        #2.token错误，返回None(我不处理，交给下一个认证类处理，则默认是None)
        user_object = models.UserInfo.objects.filter(token=token).first()
        if not user_object:
            return None

        #认证成功
        return (user_object,token)  #request.user/request.auth



class UserAuthentication(BaseAuthentication):
    """
    用户认证，用户必须先登录
    """
    def authenticate(self, request):
        token = request.META.get('HTTP_AUTHORIZATION',None)
        if not token:
            ###引起异常，程序不再往下走，后面的认证也不再做，直接终止
            raise exceptions.AuthenticationFailed()

        user_object = models.UserInfo.objects.filter(token=token).first()
        if not user_object:
            raise exceptions.AuthenticationFailed()

        return (user_object,token)


class SchoolTopicUserAuthentication(BaseAuthentication):
    """
    虽然数据库设置为允许学校和物品类型字段为空，但是我们还是不允许为空好些，所以要认证
    """

    def authenticate(self, request):
        token = request.META.get('HTTP_AUTHORIZATION',None)
        school = request.data.get('school',None)
        topic = request.data.get('topic',None)
        print("认证类:",request.data)
        if not token or not school or not topic:
            ###引起异常，程序不再往下走，后面的认证也不再做，直接终止
            raise exceptions.AuthenticationFailed()
        user_object = models.UserInfo.objects.filter(token=token).first()
        school_object = models.SchoolArea.objects.filter(id=school).first()
        ####物品类型
        topic_object = models.Topic.objects.filter(id=topic).first()
        if not user_object or not school_object or not topic_object:
            raise exceptions.AuthenticationFailed()

        return (user_object,token)